package com.xuecheng.content.service.impl;




import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.content.model.dto.CourseBaseDTO;
import com.xuecheng.api.content.model.dto.CourseTeacherDTO;
import com.xuecheng.api.content.model.dto.TeachplanDTO;
import com.xuecheng.api.content.model.qo.QueryCourseBaseModel;
import com.xuecheng.api.system.model.dto.CourseCategoryDTO;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.enums.common.AuditEnum;
import com.xuecheng.common.enums.common.CommonEnum;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.enums.content.CourseChargeEnum;
import com.xuecheng.common.enums.content.CourseModeEnum;
import com.xuecheng.common.exception.BusinessException;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.JsonUtil;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.content.agent.SystemApiAgent;
import com.xuecheng.content.common.constant.ContentErrorCode;
import com.xuecheng.content.common.constant.CoursePubTemplateKey;
import com.xuecheng.content.controller.CourseAuditController;
import com.xuecheng.content.convert.CourseBaseConvert;
import com.xuecheng.content.convert.CoursePubConvert;
import com.xuecheng.content.entity.CourseBase;
import com.xuecheng.content.entity.CourseMarket;
import com.xuecheng.content.entity.CoursePub;
import com.xuecheng.content.entity.CourseTeacher;
import com.xuecheng.content.mapper.CourseBaseMapper;
import com.xuecheng.content.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;


/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Autowired
    private CourseMarketService courseMarketService;
    @Autowired
    private CourseBaseService courseBaseService;
    @Autowired
    private TeachplanService teachplanService;
    @Autowired
    private SystemApiAgent systemApiAgent;
    @Autowired
    private CourseTeacherService courseTeacherService;
    @Autowired
    private CoursePubService coursePubService;
    /*
    * 实现步骤
    *   1.是否需要开启事务（查询不需要开启，增删改查时需要开启）
    *   2.判断关键数据（代码健壮性）
    *          关键数据：数据来源于前端
    *           分页数据需要判断：pageNo、pageSize
    *           查询条件对象数据不需要判断
    *   3.构建Page（MP）对象
    *   4.构建查询构建对象
    *   5.查询数据
    *       分页对象Page
    *       查询构件对象
    *   6.将查询结果封装返回
    *
    * */
    @Override
    public PageVO queryCourseBaseList(PageRequestParams params, QueryCourseBaseModel model,Long companyId) {

        //2.判断关键数据（代码健壮性）
        //关键数据：数据来源于前端
        //分页数据需要判断：pageNo、pageSize
        if (params.getPageNo() < 1){
            params.setPageNo(PageRequestParams.DEFAULT_PAGE_NUM);
        }
        if (params.getPageSize() < 1){
            params.setPageSize(PageRequestParams.DEFAULT_PAGE_SIZE);
        }

        //3.构建Page（MP）对象
        Page<CourseBase> page = new Page<>(params.getPageNo(), params.getPageSize());


        //4.构建查询构件对象
        LambdaQueryWrapper<CourseBase> queryWrapper = new LambdaQueryWrapper<>();

        if (!(ObjectUtils.nullSafeEquals(companyId, CourseAuditController.OPERATION_FLAG))){
            queryWrapper.eq(CourseBase ::getCompanyId,companyId);
        }
        //完整版
        //课程名称(模糊匹配)
        if (StringUtil.isNotBlank(model.getCourseName())){
            queryWrapper.like(CourseBase::getName,model.getCourseName());
        }
        //课程审核状态（精确匹配）
        if (StringUtil.isNotBlank(model.getAuditStatus())) {
            queryWrapper.eq(CourseBase::getAuditStatus, model.getAuditStatus());
        }

        //课程删除状态（精确匹配）
        queryWrapper.eq(CourseBase::getStatus,CommonEnum.USING_FLAG.getCode());

        queryWrapper.orderByDesc(CourseBase::getChangeDate);
        //5.查询数据
        //      分页对象Page
        //      查询构件对象
        Page<CourseBase> pageResult = this.page(page, queryWrapper);

        List<CourseBase> records = pageResult.getRecords();
        long total = pageResult.getTotal();

        //封装到DTO里面
        List<CourseBaseDTO> dtos = Collections.EMPTY_LIST;
        if (!CollectionUtils.isEmpty(records)){
            dtos =new ArrayList<>();
            //对象属性映射（MapStruct）--写一行代码就代表了属性赋值
            dtos = CourseBaseConvert.INSTANCE.entitys2dtos(records);

        }


        //6.将查询结果封装返回
        PageVO pageVO = new PageVO<>(dtos, total, params.getPageNo(), params.getPageSize());

        return pageVO;
    }

    /*
    *   1.开启事务
    *   2.判断关键数据
    *   3.判断业务数据
    *   4.判断数据是否是要被赋值
    *   5.将dto转为po数据
    *   6.保存数据并返回结果，判断结果是否成功
    *   7.如果操作成功，将数据转为dto并返回
    * */
    @Transactional
    @Override
    public CourseBaseDTO createCourseBase(CourseBaseDTO dto) {

       // 2.判断关键数据
        verifyCourseMsg(dto);

       // 3.判断业务数据（添加没有业务数据判断）
        //判断收费课程，价格不能为空，必须要大于0
        if (CourseChargeEnum.CHARGE_YES.getCode().equals(dto.getCharge())){
            if (ObjectUtils.isEmpty(dto.getPrice())||dto.getPrice().floatValue() <=0){
                throw new BusinessException("收费课程价格非法，请填入合法的价格");
            }
        }else {
            //课程为免费课程，价格为0
            dto.setPrice(new BigDecimal("0"));
        }
       // 4.判断数据是否是要被赋值（默认值）
        dto.setAuditStatus(CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode());

       // 5.将dto转为po数据
        CourseBase courseBase = CourseBaseConvert.INSTANCE.dto2entity(dto);

        // 6.保存数据并返回结果，判断结果是否成功
        boolean courseSaveResult = this.save(courseBase);
        if (!courseSaveResult) {
            throw new RuntimeException("课程基础信息保存失败了，小伙子！！！");
        }
        CourseMarket courseMarket = new CourseMarket();
        courseMarket.setCourseId(courseBase.getId());
        courseMarket.setCharge(dto.getCharge());
        courseMarket.setPrice(dto.getPrice().floatValue());

        boolean marketResult = courseMarketService.save(courseMarket);
        if (!marketResult) {
            throw new RuntimeException("课程营销信息保存失败了，小伙子！！");
        }

        // 7.如果操作成功，将数据转为dto并返回
        Long id = courseBase.getId();
        CourseBase po = this.getById(id);
        CourseBaseDTO resultDTO = CourseBaseConvert.INSTANCE.entity2dto(po);
        resultDTO.setCharge(dto.getCharge());
        resultDTO.setPrice(dto.getPrice());
        return resultDTO;
    }


    //判断关键数据是否符合我们后端项目的使用
    private void verifyCourseMsg(CourseBaseDTO dto) {
        if (ObjectUtils.isEmpty(dto.getCompanyId())) {
            // 业务异常：程序员在做业务判断时，数据有问题。
            // 异常：
            //    1.终止程序
            //    2.传递错误信息
            //    3.使用运行时异常来抛出
            //        运行时异常不需在编译期间处理
            ExceptionCast.cast(ContentErrorCode.E_120018);
        }

        if (StringUtil.isBlank(dto.getName())) {
            ExceptionCast.cast(ContentErrorCode.E_120004);
        }

        if (StringUtil.isBlank(dto.getMt())) {
            ExceptionCast.cast(ContentErrorCode.E_120002);
        }

        if (StringUtil.isBlank(dto.getSt())) {
            ExceptionCast.cast(ContentErrorCode.E_120003);
        }

        if (StringUtil.isBlank(dto.getGrade())) {
            ExceptionCast.cast(ContentErrorCode.E_120007);
        }

        if (StringUtil.isBlank(dto.getTeachmode())) {
            ExceptionCast.cast(ContentErrorCode.E_120006);
        }

        if (StringUtil.isBlank(dto.getUsers())) {
            ExceptionCast.cast(ContentErrorCode.E_120019);
        }

        if (StringUtil.isBlank(dto.getCharge())) {
            ExceptionCast.cast(ContentErrorCode.E_120020);
        }
    }

    private void getCourseByLogic(Long companyId, Long courseBaseId) {

        CourseBase courseBase = getCourseBaseByBaseId(courseBaseId, companyId);

        String auditStatus = courseBase.getAuditStatus();
        if (CourseAuditEnum.AUDIT_PASTED_STATUS.getCode().equals(auditStatus)||
                CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode().equals(auditStatus)||
                CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode().equals(auditStatus)
        ) {
            throw new RuntimeException("课程审核状态异常");
        }
    }

    //更新数据（修改）
    @Override
    @Transactional
    public CourseBaseDTO modifyCourseBase(CourseBaseDTO dto) {
        //2.判断关键数据
        // 	前端传递过来的数据
        // 	需要比新增时要多判断一个数据：courseBaseId
        // 		修改课程基础信息是必须携带id值的
        verifyCourseMsg(dto);

        Long courseBaseId = dto.getCourseBaseId();
        if (ObjectUtils.isEmpty(courseBaseId)) {
            throw new RuntimeException("修改课程id不能为空");
        }

        // 3.判断业务数据
        // 	判断是否存在
        // 	判断是否是同一家机构
        // 	判断是否删除
        // 	判断审核状态
        // 		未提交--新创建出的课程
        // 		审核未通过--运营审核没有通过
        // 		只有这两个状态才可以修改课程基础信息
        getCourseByLogic(dto.getCompanyId(), courseBaseId);

        //     课程营销
        CourseMarket courseMarket = getCourseMarketByCourseId(courseBaseId);

        // 4.将dto转为po
        //     课程基础信息表
        //         有些内容是不容修改的：companyid、auditstatus、status

        CourseBase po = CourseBaseConvert.INSTANCE.dto2entity(dto);

        //5.保存数据
        //    CourseBase
        //    CourseMarket
        // 为了防止前端乱意修改内容
        po.setCompanyId(null);
        po.setAuditStatus(null);
        po.setStatus(null);

        boolean baseResult = this.updateById(po);

        if (!baseResult) {
            throw new RuntimeException("课程信息修改失败");
        }

        //     课程营销数据表
        //         charge price
        // 如果使用mq修改一张表中的极个别数据，UpdateWrapper
        // update course_market set charge=xxx,price=xxx  where courseid=xx
        LambdaUpdateWrapper<CourseMarket> marketUpdateWrapper = new LambdaUpdateWrapper<>();
        marketUpdateWrapper.set(CourseMarket::getCharge,dto.getCharge());

        String charge = dto.getCharge();
        if (CourseChargeEnum.CHARGE_YES.getCode().equals(charge)) {

            BigDecimal price = dto.getPrice();
            if (ObjectUtils.isEmpty(price)) {
                throw new RuntimeException("收费课程价格不能为空");
            }

            marketUpdateWrapper.set(CourseMarket::getPrice, dto.getPrice().floatValue());
        } else {
            // 如果课程为免费，需要价格赋值为0
            marketUpdateWrapper.set(CourseMarket::getPrice, 0F);
        }
        marketUpdateWrapper.eq(CourseMarket::getCourseId, courseBaseId);

        boolean marketResult = courseMarketService.update(marketUpdateWrapper);

        //      修改数据时要判断修改后结果
        if (!marketResult) {
            throw new RuntimeException("修改课程营销数据失败");
        }

        // 6.将修改后的最新数据返回给前端
        CourseBaseDTO resultDTO = getLastCourseBaseDTO(dto, courseBaseId);
        return resultDTO;
    }

    private CourseBaseDTO getLastCourseBaseDTO(CourseBaseDTO dto, Long id) {
        CourseBase po = this.getById(id);

        CourseBaseDTO resultDTO = CourseBaseConvert.INSTANCE.entity2dto(po);
        resultDTO.setCharge(dto.getCharge());
        resultDTO.setPrice(dto.getPrice());
        return resultDTO;
    }


    //根据id获得基础数据
    @Override
    public CourseBaseDTO getByCourseBaseId(Long courseBaseId, Long companyId) {
        //1.判断关键数据
        if (ObjectUtils.isEmpty(courseBaseId)||ObjectUtils.isEmpty(companyId)){
            throw new RuntimeException("宝，传入的参数不对呀。。");
        }
        //2.判断业务数据
        CourseBase courseBase = getCourseBaseByBaseId(courseBaseId, companyId);
        CourseMarket courseMarket = getCourseMarketByCourseId(courseBaseId);
        //3.查询数据并转为dto返回
        CourseBaseDTO courseBaseDTO = CourseBaseConvert.INSTANCE.entity2dto(courseBase);
        courseBaseDTO.setCharge(courseMarket.getCharge());
        courseBaseDTO.setPrice(new BigDecimal(courseMarket.getPrice().toString()));
        return courseBaseDTO;
    }


    //根据id获得基础数据（判断课程营销数据）
    private CourseMarket getCourseMarketByCourseId(Long courseBaseId) {
        LambdaQueryWrapper<CourseMarket> marketQueryWrapper = new LambdaQueryWrapper<>();
        marketQueryWrapper.eq(CourseMarket::getCourseId, courseBaseId);

        CourseMarket courseMarket = courseMarketService.getOne(marketQueryWrapper);

        if (ObjectUtils.isEmpty(courseMarket)) {
            throw new RuntimeException("课程营销数据不存在");
        }
        return courseMarket;
    }

    //根据id获得基础数据（判断业务数据）
    private CourseBase getCourseBaseByBaseId(Long courseBaseId, Long companyId) {
        LambdaQueryWrapper<CourseBase> baseQueryWrapper = new LambdaQueryWrapper<>();
        baseQueryWrapper.eq(CourseBase::getId, courseBaseId);
        baseQueryWrapper.eq(CourseBase::getCompanyId, companyId);
        // baseQueryWrapper.eq(CourseBase::getStatus, CommonEnum.USING_FLAG.getCodeInt());

        CourseBase courseBase = this.getOne(baseQueryWrapper);

        if (ObjectUtils.isEmpty(courseBase)) {
            throw new RuntimeException("课程不存在");
        }

        Integer status = courseBase.getStatus();
        if (!(CommonEnum.USING_FLAG.getCodeInt().equals(status))) {
            throw new RuntimeException("课程信息已经被删除");
        }
        return courseBase;
    }


    //根据ID删除基础数据
    @Override
    @Transactional
    public void removeCourseBase(Long courseBaseId, Long companyId) {
        //1.判断关键数据的合法性
        if (ObjectUtils.isEmpty(courseBaseId)||ObjectUtils.isEmpty(companyId)){
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.根据ID获取课程基础信息并进行相应的判断
        CourseBase courseBase = getById(courseBaseId);
        verifyPO(companyId,courseBase);
        String auditStatus = courseBase.getAuditStatus();
        if (CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode().equals(auditStatus) ||
                CourseAuditEnum.AUDIT_PASTED_STATUS.getCode().equals(auditStatus) ||
                CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode().equals(auditStatus)
        ) {
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }
        //3.修改课程信息状态值（逻辑删除）
        LambdaUpdateWrapper<CourseBase> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CourseBase::getStatus,CommonEnum.DELETE_FLAG.getCodeInt());
        updateWrapper.set(CourseBase::getChangeDate, LocalDateTime.now());

        updateWrapper.eq(CourseBase::getId, courseBase.getId());

        boolean result = update(updateWrapper);
        if (!result) {
            ExceptionCast.cast(ContentErrorCode.E_120017);
        }
    }

    //课程审核--提交课程
    @Override
    @Transactional
    public void commitCourseBase(Long courseBaseId, Long companyId) {
        if (ObjectUtils.isEmpty(companyId)||ObjectUtils.isEmpty(companyId)){
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //判断业务数据
        getCourseByLogic(companyId,courseBaseId);
        //修改课程审核状态
        LambdaUpdateWrapper<CourseBase> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CourseBase::getAuditStatus, CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode());
        updateWrapper.set(CourseBase::getChangeDate, LocalDateTime.now());
        updateWrapper.eq(CourseBase::getId, courseBaseId);
        boolean result = this.update(updateWrapper);
        if (!result) {
            ExceptionCast.cast(ContentErrorCode.E_120017);
        }
    }

    //课程信息审核--运营
    @Override
    @Transactional
    public void approveCourse(CourseBaseDTO dto) {
        //1.判断关键数据
        if (StringUtils.isBlank(dto.getAuditMind()) ||
                StringUtils.isBlank(dto.getAuditStatus()) ||
                ObjectUtils.isEmpty(dto.getCourseBaseId())) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.判断业务数据
        LambdaQueryWrapper<CourseBase> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseBase::getId, dto.getCourseBaseId());
        queryWrapper.eq(CourseBase::getStatus, CommonEnum.USING_FLAG.getCodeInt());
        queryWrapper.eq(CourseBase::getAuditStatus, CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode());
        int count = this.count(queryWrapper);
        if (count<1){
            ExceptionCast.cast(ContentErrorCode.E_120023);
        }
        // 审核状态
        // 运营平台只能给课程审核状态赋值：审核通过、审核未通过
        String auditStatus = dto.getAuditStatus();
        if (CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode().equals(auditStatus)||
                CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode().equals(auditStatus)||
                CourseAuditEnum.AUDIT_UNPAST_STATUS.getCode().equals(auditStatus)){
            ExceptionCast.cast(ContentErrorCode.E_120016);
        }
        //3.修改课程审核信息
        LambdaUpdateWrapper<CourseBase> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(CourseBase::getAuditStatus, dto.getAuditStatus());
        updateWrapper.set(CourseBase::getAuditMind, dto.getAuditMind());
        //使用redis来实现
        updateWrapper.set(CourseBase ::getAuditNums,dto.getAuditNums());
        updateWrapper.eq(CourseBase::getId, dto.getCourseBaseId());
        boolean result = this.update(updateWrapper);
        if (!result){
            ExceptionCast.cast(ContentErrorCode.E_120017);
        }
    }

    /*
          主方法业务
        1.构建CoursePub数据并保存
        2.根据CoursePub内容构架DataMap数据
        3.将DataMap进行返回
     */

    //课程预览
    @Transactional
    public Map<String, Object> previewCourse(Long courseId, Long companyId) {
        //1.构建CoursePub数据并保存
        CoursePub coursePub= generateCoursePub(courseId,companyId);
        //2.根据CoursePub内容构架DataMap数据
        Map<String,Object>dataMap= generateDataMap(coursePub);
        //3.将DataMap进行返回
        return dataMap;
    }

    /*
     * 构建CoursePub数据并保存
     *   业务分析：
     *       1.判断关键数据
     *        courseId companyId
     *       2.判断业务数据
     *           课程基础信息
     *               判断是否存在
     *               判断是否是同一家机构
     *               判断是否删除
     *               判断审核状态：教学机构课程预览--未提交、审核未通过
     *           课程营销
     *               判断是否存在：根据courseid
     *           课程计划
     *               获得课程计划：根据courseId和companyId（树形结构）
     *           课程教师
     *               判断教师信息是否存在：一定要确保课程最少有一个教师信息
     *
     *           课程分类数据并完善Coursepub数据
     *               调用system服务获得课程分类的名称
     *                  发送feign接口获得课程分类的详细信息：大分类、小分类
     *       3.保存课程发布数据
     *           CoursePub数据保存数据库中
     *               课程基础信息  课程营销json（冗余字段charge、price）  课程计划json  课程教师json
     *              完善数据：1.课程分类
     *                      2.课程发布要核课程基础信息进行关联
     *                          将courseBaseId赋值到CoursePub中的courseId中
     *       4.保存课程发布数据
     *              判断课程发布数据是否存在（查询条件 CourseId --> CourseBase： id）
     *                  如果不存在：创建出课程的CoursePub数据
     *                  如果存在：修改课程的CoursePub数据
     *              操作完成后，判断操作的结果
     *       4.将coursePub数据返回
     * */
    private CoursePub generateCoursePub(Long courseId, Long companyId) {
        //1.判断关键数据
        if (ObjectUtils.isEmpty(courseId)||ObjectUtils.isEmpty(companyId)){
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.判断业务数据
        CourseBaseDTO courseBaseDTO = courseBaseService.getByCourseBaseId(courseId, companyId);
        String auditStatus = courseBaseDTO.getAuditStatus();
        if (CourseAuditEnum.AUDIT_PASTED_STATUS.getCode().equals(auditStatus)||
            CourseAuditEnum.AUDIT_COMMIT_STATUS.getCode().equals(auditStatus)||
            CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode().equals(auditStatus)){
            ExceptionCast.cast(ContentErrorCode.E_120015);
        }
        //课程营销
        LambdaQueryWrapper<CourseMarket> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CourseMarket::getCourseId,courseId);
        CourseMarket courseMarket = courseMarketService.getOne(lambdaQueryWrapper);
        //课程计划
        TeachplanDTO teachplanTreeNodes = teachplanService.queryTreeNodesByCourseId(courseId, companyId);
        //课程教师
        LambdaQueryWrapper<CourseTeacher> courseTeacherLambdaQueryWrapper = new LambdaQueryWrapper<>();
        courseTeacherLambdaQueryWrapper.eq(CourseTeacher::getCourseId,courseId);

        List<CourseTeacher> courseTeachers = courseTeacherService.list(courseTeacherLambdaQueryWrapper);
        //课程分类数据并完善CoursePub数据，调用system服务获得课程分类的名称
        String mt = courseBaseDTO.getMt();
        String st = courseBaseDTO.getSt();
        RestResponse<CourseCategoryDTO> mtResponse = systemApiAgent.getCourseCategoryById4s(mt);
        if (!(mtResponse.isSuccessful())){
            ExceptionCast.castWithCodeAndDesc(mtResponse.getCode(),mtResponse.getMsg());
        }
        RestResponse<CourseCategoryDTO> stResponse = systemApiAgent.getCourseCategoryById4s(st);
        if (!(stResponse.isSuccessful())){
            ExceptionCast.castWithCodeAndDesc(stResponse.getCode(),stResponse.getMsg());
        }
        CourseCategoryDTO mtEntity = mtResponse.getResult();
        CourseCategoryDTO stEntity = stResponse.getResult();
        //构建coursePub数据并保存操作
        //课程基础数据
        CoursePub coursePub = CoursePubConvert.INSTANCE.courseBase2coursePub(courseBaseDTO);
        //课程营销数据
        String marketJson = JsonUtil.objectTojson(courseMarket);
        coursePub.setMarket(marketJson);
        coursePub.setPrice(courseMarket.getPrice());
        coursePub.setCharge(courseMarket.getCharge());
        //课程计划数据
        String teachplanJson = JsonUtil.objectTojson(teachplanTreeNodes);
        coursePub.setTeachplan(teachplanJson);
        //课程教师
        String ts = JsonUtil.listTojson(courseTeachers);
        coursePub.setTeachers(ts);
        //课程分类数据
        coursePub.setMtName(mtEntity.getName());
        coursePub.setStName(stEntity.getName());

        coursePub.setCourseId(courseId);

        //3.保存课程发布数据
        LambdaQueryWrapper<CoursePub> pubQueryWrapper = new LambdaQueryWrapper<>();
        pubQueryWrapper.eq(CoursePub::getCourseId,courseId);
        pubQueryWrapper.eq(CoursePub::getCompanyId,companyId);
        CoursePub po = coursePubService.getOne(pubQueryWrapper);

        boolean result =false;
        //判断课程发布数据是否存在
        if (ObjectUtils.isEmpty(po)){
            coursePub.setCourseId(courseBaseDTO.getCourseBaseId());
            result =coursePubService.save(coursePub);
        }else {
            coursePub.setId(po.getId());
            result =coursePubService.updateById(coursePub);
        }
        if (!result){
            ExceptionCast.cast(ContentErrorCode.E_120204);
        }
        //将coursePub数据返回
        return coursePub;
    }

    private Map<String, Object> generateDataMap(CoursePub coursePub) {
        //1.构建数据模型对象
        HashMap<String, Object> dataMap = new HashMap<>();
        //2.构建coursePub
        dataMap.put(CoursePubTemplateKey.COURSEPUB,coursePub);
        //3.构建courseMarket
        String market = coursePub.getMarket();
        CourseMarket courseMarket = JsonUtil.jsonToObject(market, CourseMarket.class);
        dataMap.put(CoursePubTemplateKey.COURSEMARKET,courseMarket);
        //4.构建课程计划
        String teachplan = coursePub.getTeachplan();
        TeachplanDTO teachplanDTO = JsonUtil.jsonToObject(teachplan, TeachplanDTO.class);
        dataMap.put(CoursePubTemplateKey.TEACHPLANNODE,teachplanDTO);
        //5.构建课程模式
        CourseModeEnum[] values = CourseModeEnum.values();
        dataMap.put(CoursePubTemplateKey.COURSETEACHMODEENUMS,values);
        //6.构建课程教师
        String teachers = coursePub.getTeachers();
        CourseTeacherDTO courseTeacherDTO = JsonUtil.jsonToObject(teachers, CourseTeacherDTO.class);
        dataMap.put(CoursePubTemplateKey.COURSETEACHER,courseTeacherDTO);

        return dataMap;
    }


    //判断课程是否存在且为同一家机构
    private void verifyPO(Long companyId, CourseBase courseBase) {
        // 判断课程数据是否存在
        if (ObjectUtils.isEmpty(courseBase)) {
            ExceptionCast.cast(ContentErrorCode.E_120013);
        }
        // 判断是否是同一家机构
        if (!(ObjectUtils.nullSafeEquals(companyId, courseBase.getCompanyId()))) {
            ExceptionCast.cast(CommonErrorCode.E_100108);
        }
    }



}
